#include <stdio.h>

/*
 * 函数指针调用
 */

int func()
{
    int a = 0;
    
    a++;

	return 0;
}

int main()
{
    int (* point)();

    point = func;
    point();

	return 0;
}

#if 0

1.获取函数地址
2.存入栈。

/*
 * intel
 */
0000000000001129 <func>:
    1129:	f3 0f 1e fa          	endbr64 
    112d:	55                   	push   %rbp				// rsp=rsp-8, (rsp)=rbp ===> subq $8,%rsp, movq %rbp,(%rsp)
    112e:	48 89 e5             	mov    %rsp,%rbp		// rbp=rsp
    1131:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)	// a = rpb-0x4 = 0
    1138:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)	// a = 1
    113c:	b8 00 00 00 00       	mov    $0x0,%eax		// return 0
    1141:	5d                   	pop    %rbp				// rbp=(rsp), rsp+8 ===> movq (%rsp),%rbp, addq $8, %rsp
    1142:	c3                   	retq					// ===> pop %rip  ===> mov %rip, %rsp, add $8, (%rsp)

0000000000001143 <main>:
    1143:	f3 0f 1e fa          	endbr64 
    1147:	55                   	push   %rbp
    1148:	48 89 e5             	mov    %rsp,%rbp		// rbp=rsp
    114b:	48 83 ec 10          	sub    $0x10,%rsp		// rsp=rsp-0x10
    114f:	48 8d 05 d3 ff ff ff 	lea    -0x2d(%rip),%rax		# 1129 <func> // 0x1156 - 0x2d = 0x1129 = func, rip指向下一条指令，
    1156:	48 89 45 f8          	mov    %rax,-0x8(%rbp)	// rbp-0x8 = func
    115a:	48 8b 55 f8          	mov    -0x8(%rbp),%rdx	// rdx = func
    115e:	b8 00 00 00 00       	mov    $0x0,%eax		// eax = 0
    1163:	ff d2                	callq  *%rdx			// func()
    1165:	b8 00 00 00 00       	mov    $0x0,%eax		// return 0
    116a:	c9                   	leaveq					// ===> mov %rbp,%rsp, pop %rbp
    116b:	c3                   	retq					// ===> pop %rip
    116c:	0f 1f 40 00          	nopl   0x0(%rax)		// 流水线指令优化

/*
 * arm
 */
000000000040051c <func>:
  40051c:	d10043ff 	sub	sp, sp, #0x10		// sp = sp - 0x10
  400520:	b9000fff 	str	wzr, [sp, #12]		// sp + 12 = 0
  400524:	b9400fe0 	ldr	w0, [sp, #12]		// sp + 12 = w0
  400528:	11000400 	add	w0, w0, #0x1		// w0 = w0 + 1
  40052c:	b9000fe0 	str	w0, [sp, #12]		// sp + 12 = w0
  400530:	52800000 	mov	w0, #0x0            // #0
  400534:	910043ff 	add	sp, sp, #0x10		// sp = sp + 0x10
  400538:	d65f03c0 	ret

000000000040053c <main>:
  40053c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!	// sp = sp-32, sp = x29, sp+8 = x30,保护栈
  400540:	910003fd 	mov	x29, sp					// fp = sp
  400544:	90000000 	adrp	x0, 400000 <_init-0x3b0>	// x0 = 400000
  400548:	91147000 	add	x0, x0, #0x51c			// x0 = 400000 + 0x51c = 0x40051C = func
  40054c:	f9000fa0 	str	x0, [x29, #24]			// x29+24 = x0
  400550:	f9400fa0 	ldr	x0, [x29, #24]			// x0 = 0x29+24
  400554:	d63f0000 	blr	x0						// func()
  400558:	52800000 	mov	w0, #0x0                // #0
  40055c:	a8c27bfd 	ldp	x29, x30, [sp], #32		// x29 = sp, x30 = sp + 8, sp = sp + 32,恢复栈
  400560:	d65f03c0 	ret							// 子程序返回指令，返回地址默认保存在LR(X30)
  400564:	00000000 	.inst	0x00000000 ; undefined

#endif	
